import { cloneDeep } from 'lodash-es';
import { MODEL_NAME } from '../../constants/model-names';
import { EVENTS, type IEventBus } from '../../events';
import type { BaseSnapshot } from '../../systems/save';
import { BaseModel } from '../base';
import {
  FIVE_ELEMENT,
  FIVE_ELEMENT_MAP,
  type FiveElement,
} from '../../constants/five-elements';
import {
  SPIRITUAL_ROOT,
  SPIRITUAL_ROOT_LEVEL_DESC_MAP,
} from '../../data/spiritual-root';

export class SpiritualRootReader {
  static formatterSpiritualRoot(attributeKey: FiveElement) {
    return FIVE_ELEMENT_MAP[attributeKey].label;
  }
}

export type SpiritualRootKey = FiveElement;

type SpiritualRootConfig = Record<SpiritualRootKey, number>;

interface SpiritualRootV1 extends BaseSnapshot {
  version: 1;
  config: SpiritualRootConfig;
  skillPoints: number;
}

export type SpiritualRootSnapshot = SpiritualRootV1;

export class SpiritualRootModel extends BaseModel {
  public name = MODEL_NAME.SPIRITUAL_ROOT;
  private bus: IEventBus;

  private config: SpiritualRootConfig = {
    [FIVE_ELEMENT.METAL]: 0,
    [FIVE_ELEMENT.WOOD]: 0,
    [FIVE_ELEMENT.WATER]: 0,
    [FIVE_ELEMENT.FIRE]: 0,
    [FIVE_ELEMENT.EARTH]: 0,
  };
  private tempConfig: SpiritualRootConfig = {
    [FIVE_ELEMENT.METAL]: 0,
    [FIVE_ELEMENT.WOOD]: 0,
    [FIVE_ELEMENT.WATER]: 0,
    [FIVE_ELEMENT.FIRE]: 0,
    [FIVE_ELEMENT.EARTH]: 0,
  };
  private skillPoints = 10;
  private tempSkillPoints = this.skillPoints;
  private customSpiritualRootLevelName: Record<number, string> = {};

  constructor(bus: IEventBus) {
    super();
    this.bus = bus;
  }

  public addSpiritualRootPoint(key: SpiritualRootKey) {
    if (this.tempSkillPoints <= 0) return false;
    this.tempConfig[key] += 1;
    this.tempSkillPoints -= 1;
    this.bus.emit(EVENTS.SPIRITUAL_ROOT_STATE_UPDATE);
    return true;
  }

  public subSpiritualRootPoint(key: SpiritualRootKey) {
    if (this.tempConfig[key] <= 0) return false;
    this.tempConfig[key] -= 1;
    this.tempSkillPoints += 1;
    this.bus.emit(EVENTS.SPIRITUAL_ROOT_STATE_UPDATE);
    return true;
  }

  public submitSpiritualRoot() {
    this.config = cloneDeep(this.tempConfig);
    this.skillPoints = this.tempSkillPoints;
    this.bus.emit(EVENTS.SPIRITUAL_ROOT_STATE_UPDATE);
  }

  /** 是否拥有这个灵根 */
  public hasSpiritualRoot(key: SpiritualRootKey) {
    return this.config[key] > 0;
  }

  /** 获取一种灵根等级 */
  public getSpiritualRootLevel(key: SpiritualRootKey) {
    return this.config[key];
  }

  /** 获取某个灵根的升级条件 */
  public getSpiritualRootLevelCondition(key: SpiritualRootKey) {
    const spiritualRoot = SPIRITUAL_ROOT[key];
    const levels = spiritualRoot.levels;
    const levelConfig = levels[this.getSpiritualRootLevel(key)];
    const upgradeConditions = levelConfig?.upgradeConditions || [];
    return upgradeConditions;
  }

  /** 获取灵根等级名称 */
  public getSpiritualRootLevelName(level: number) {
    return (
      SPIRITUAL_ROOT_LEVEL_DESC_MAP[level] ||
      this.customSpiritualRootLevelName[level] ||
      '域外天魔'
    );
  }

  /** 给某个灵根提升一级 */
  public upgradeSpiritualRoot(key: SpiritualRootKey) {
    this.config[key] += 1;
    this.bus.emit(EVENTS.SPIRITUAL_ROOT_STATE_UPDATE);
  }

  public getConfig() {
    return this.config;
  }

  public getTempConfig() {
    return this.tempConfig;
  }

  public getSkillPoints() {
    return this.skillPoints;
  }

  public getTempSkillPoints() {
    return this.tempSkillPoints;
  }

  save(): SpiritualRootSnapshot {
    return {
      version: 1,
      config: this.getConfig(),
      skillPoints: this.getSkillPoints(),
    };
  }

  load(snapshot: SpiritualRootSnapshot) {
    this.config = snapshot.config;
    this.tempConfig = cloneDeep(this.config);
    this.skillPoints = snapshot.skillPoints;
    this.tempSkillPoints = this.skillPoints;
  }
}
